import { http } from '@/request/http'
import { SmUtils } from '@/utils/smUtils'
import { useSystemStore } from '@/stores/system'
import { initRoleVO, type RoleVO } from '@/request/api/role'
import type { PageDTO, PageVO } from '@/type/type'
import type { MakeOptional } from '@/type'

type BaseUser = {
  // 主键
  id: number
  // 头像
  avatar: string
  // 用户名
  username: string
  // 邮箱
  email: string
  // 经验值
  experience: number
  // 状态（0不可用，1可用）
  status: boolean
}

export type UserDTO = MakeOptional<BaseUser> & {
  // 角色ID
  roleId: number | undefined
  // 性别 -1女 0保密 1男
  gender: number | undefined
  // 密码
  password: string | undefined
}

export type UserVO = BaseUser & {
  // 用户名
  username: string
  // 性别 -1女 0保密 1男
  gender: string
  // 创建时间
  createTime: Date
  // 角色
  role: RoleVO

  token: string
}

export const initUserDTO = (): UserDTO => {
  return {
    id: undefined,
    roleId: undefined,
    avatar: undefined,
    username: undefined,
    gender: undefined,
    email: undefined,
    experience: undefined,
    password: undefined,
    status: undefined
  }
}

export const initUserVO = (): UserVO => {
  return {
    id: 0,
    avatar: '',
    username: '',
    gender: '',
    email: '',
    experience: 0,
    status: false,
    createTime: new Date(),
    role: initRoleVO(),
    token: ''
  }
}

const map = new Map<string, number>()
map.set('男', 1)
map.set('保密', 0)
map.set('女', -1)

export const userVO2DTO = (vo: UserVO): UserDTO => {
  return {
    id: vo.id,
    roleId: vo.role.id,
    avatar: vo.avatar,
    username: vo.username,
    gender: map.get(vo.gender),
    email: vo.email,
    experience: vo.experience,
    password: undefined,
    status: vo.status
  }
}

/* 交换密钥 */
export const exchangeSm2Api = () => {
  return http<string>({
    url: `/exchange/sm2`,
    method: 'get'
  })
}

export const loginApi = (username: string, password: string) => {
  return http<UserVO>({
    url: `/login`,
    method: 'post',
    headers: {
      'content-type': 'application/x-www-form-urlencoded'
    },
    data: {
      username: getEnFiled(username),
      password: getEnFiled(password)
    }
  })
}

export const refreshTokenApi = (id: number) => {
  return http<string>({
    url: `/refresh/token`,
    method: 'get',
    params: {
      id: id
    }
  })
}

export const insertUserApi = (email: string, password: string) => {
  return http<boolean>({
    url: `/user/insert`,
    method: 'post',
    headers: {
      'content-type': 'application/x-www-form-urlencoded'
    },
    data: {
      email: getEnFiled(email),
      password: getEnFiled(password)
    }
  })
}

export const getUserApi = () => {
  return http<UserVO>({
    url: `/user/info`,
    method: 'get'
  })
}

export const updateUserApi = (user: UserDTO) => {
  user.password = getEnFiled(user.password)
  user.email = getEnFiled(user.email)
  return http<boolean>({
    url: `/user/update`,
    method: 'put',
    data: user
  })
}

export const getUserAdminPageApi = (page: PageDTO) => {
  return http<PageVO<UserVO>>({
    url: `/admin/user/page`,
    method: 'get',
    params: {
      dto: JSON.stringify(page)
    }
  })
}

export const getUserDistributionAdminApi = () => {
  return http<{
    keys: string[]
    values: number[]
  }>({
    url: `/admin/user/distribution`,
    method: 'get'
  })
}

export const insertUserAdminApi = (user: UserDTO) => {
  user.password = getEnFiled(user.password)
  return http<boolean>({
    url: `/admin/user/insert`,
    method: 'post',
    data: user
  })
}

const getEnFiled = (filed: string | undefined) => {
  if (filed !== undefined && filed !== '') {
    filed = SmUtils.enSm2(useSystemStore().backendSm2.publicKey, filed)
  }
  return filed
}
